<?php

/**
 * Framework
 *
 * @author      Joe Stump <joe@joestump.net>
 * @copyright   (c) 2005 2006 Joseph C. Stump. All rights reserved. 
 * @license     http://www.opensource.org/licenses/bsd-license.php
 * @package     Framework
 * @filesource
 */

/**
 * FRAMEWORK_BASE_PATH
 *
 * Dynamically figure out where in the filesystem we are located.
 *
 * @author Joe Stump <joe@joestump.net>
 * @global string FRAMEWORK_BASE_PATH Absolute path to our framework
 */

// Following added to ensure Framework function above root - ian
define('FRAMEWORK_BASE_PATH',dirname(__FILE__));

// Edit include path 
$path = ini_get('include_path');
$path = FRAMEWORK_BASE_PATH.DIRECTORY_SEPARATOR.PATH_SEPARATOR.$path;
ini_set('include_path',$path);


// Edit PEAR include
$path = ini_get('include_path');
$path = FRAMEWORK_BASE_PATH.'/Lib/PEAR/'.PATH_SEPARATOR.$path;
ini_set('include_path',$path);

if (!function_exists('__autoload')) {
    /**
     * __autoload
     *
     * Autoload is ran by PHP when it can't find a class it is trying to load.
     * By naming our classes intelligently we should be able to load most 
     * classes dynamically.
     *
     * @author      Joe Stump <joe@joestump.net>
     * @param       string      $class Class name we're trying to load
     * @return      void
     * @package     Framework
     */
    function __autoload($class)
    {
    	$file = str_replace('_','/',$class.'.php');     
        include_once($file);
    }
}



define('FRAMEWORK_ERROR_MODULE_INIT', 2);
define('FRAMEWORK_ERROR_MODULE_EVENT', 4);
define('FRAMEWORK_ERROR_MODULE_STATUS', 128);
define('FRAMEWORK_ERROR_AUTH', 8);
define('FRAMEWORK_ERROR_PRESENTER', 16);
define('FRAMEWORK_ERROR_REQUEST', 32);
define('FRAMEWORK_ERROR_SITE', 64);



/**
 * Framework
 *
 * This is the base controller of the framework. It handles incoming requests
 * and loads the appropriate modules, presenters, etc. 
 *
 * @author Joe Stump <joe@joestump.net>
 * @package Framework
 */
abstract class Framework
{
    /**
     * $module
     *
     * @access 		public
     * @var 		object $module Instance of Framework_Module being loaded/ran
     * @static
     */
    static public $module = null;

    /**
     * $site
     *
     * @access 		public
     * @var 		Framework_Site $site Instance of Framework_Site being loaded/ran
     * @static
     */
    static public $site = null;

    /**
     * $request
     *
     * @access 		public
     * @var 		object $request Instance of Framework_Request 
     * @static
     */
    static public $request = null;


    /**
     * $db
     *
     * @access 		public
     * @var 		object $db Instance of PEAR DB 
     * @static
     * @link 		http://pear.php.net/package/DB
     */
    static public $db = null;

    /**
     * $log
     * 
     * @access 		public
     * @var			object $log Instance of PEAR Log
     * @static
     * @link 		http://pear.php.net/package/Log
     */
    static public $log = null;

    /**
     * $controller
     * 
     * @access      private
     * @var         object $controller
     * @see         Framework_Controller, Framework_Controller_Common
     */
    static private $controller = null;
	
	/**
     * $util
     * 
     * @access      public
     * @var         object $util
     * @static
     * @see         Framework_Util
     */
    static public $util = null;
    
    static public function init($site = 'Default') {
    	// Initialize the site
        self::$site = Framework_Site::factory($site);
        if (PEAR::isError(self::$site)) {
            return PEAR::raiseError(self::$site->getMessage(), 
                                    FRAMEWORK_ERROR_SITE);
        }
    }

    /**
     * start
     *
     * @access 		public
     * @return 		mixed PEAR_Error on failure, true on success
     */
    static public function start($controller = 'Web')
    {
    	
    	// Load utilities
		self::$util = new Framework_Util;
	
		// Get the controller based on  supplied argument
        self::$controller = Framework_Controller::factory($controller);
        if (PEAR::isError(self::$controller)) {
            return self::$controller;
        }

		// Based on the type of request the controller needs, 
        // build the request object which is used to collect 
        // the arguments for the module and other elements
        try {
            self::$request = Framework_Request::factory(self::$controller->requester);
        } catch (Framework_Exception $error) {
            return PEAR::raiseError($error->getMessage(), 
                                    FRAMEWORK_ERROR_REQUEST);
        }
        
   		// Prepare the site
        $result = self::$site->prepare();
        if (PEAR::isError($result)) {
            return PEAR::raiseError($result->getMessage(), 
                                    FRAMEWORK_ERROR_SITE);
        }

		// Get the controller to build the module
        self::$module = self::$controller->module();
        if (PEAR::isError(self::$module)) {
            return PEAR::raiseError(self::$module->getMessage(), 
                                    FRAMEWORK_ERROR_MODULE_INIT);
        }

        if (!in_array($controller, self::$module->controllers)) {
            return PEAR::raiseError('Invalid controller requested', 
                                    FRAMEWORK_MODULE_ERROR_INVALID_CONTROLLER);
        }

		// Controller authenticates the user
        $result = self::$controller->authenticate();
        if (PEAR::isError($result)) {
            return PEAR::raiseError($result->getMessage(), 
                                    FRAMEWORK_ERROR_AUTH);
        }

        
        
		// Controller starts
        $result = self::$controller->start();
        if (PEAR::isError($result)) {
            return PEAR::raiseError($result->getMessage(), 
                                    FRAMEWORK_ERROR_MODULE_EVENT);
        } 
        
        // Controller displays results, returns error if there is a problem
        return self::$controller->display();
    }

    /**
     * stop
     * 
     * @access 		public   
     * @return 		mixed True on success, PEAR_Error on failure
     */
    static public function stop()
    {
    	
    	// Write Session
    	session_commit();
    	
        $result = self::$controller->stop();
        if (PEAR::isError($result)) {
            return $result;
        }
        
        $result = self::$site->stop();
        if (PEAR::isError($result)) {
            return $result;
        }
        
        if (DB::isConnection(self::$db)) {
            self::$db->disconnect();
        }

        if (self::$log instanceof Log) {
            self::$log->close();
        }
       
      

        return true; 
    }
}

?>
